<template>
    <div class="template-manager">
      <!-- 顶部工具栏 -->
      <div class="header-toolbar">
        <div class="toolbar-left">
          <el-button type="primary" @click="handleUpload">
            <el-icon><Upload /></el-icon>
            上传
          </el-button>
          <el-input
            v-model="queryForm.name"
            placeholder="搜索模板名称"
            clearable
            style="width: 200px; margin-left: 12px"
            @keyup.enter="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
          <el-button type="primary" @click="handleSearch" style="margin-left: 8px">
            <el-icon><Search /></el-icon>
            查询
          </el-button>
          <el-button style="margin-left: 8px" @click="openPlaceholderDialog">
            <el-icon><Tickets /></el-icon>
            占位符获取
          </el-button>
        </div>
        <div class="toolbar-right">
          <el-button
            v-if="isBatchMode"
            type="danger"
            :disabled="selectedIds.length === 0"
            @click="handleBatchDelete"
          >
            <el-icon><Delete /></el-icon>
            批量删除
          </el-button>
          <el-button @click="isBatchMode = !isBatchMode">
            <el-icon><Select /></el-icon>
            {{ isBatchMode ? '取消批量' : '批量操作' }}
          </el-button>
          <el-button-group style="margin-left: 8px">
            <el-button :type="viewMode === 'grid' ? 'primary' : ''" @click="viewMode = 'grid'">
              <el-icon><Grid /></el-icon>
            </el-button>
            <el-button :type="viewMode === 'list' ? 'primary' : ''" @click="viewMode = 'list'">
              <el-icon><List /></el-icon>
            </el-button>
          </el-button-group>
        </div>
      </div>
  
      <!-- 内容区域 -->
      <div class="content-area">
        <!-- 网格视图 - 支持右键菜单 -->
        <div v-if="viewMode === 'grid'" class="grid-view" v-loading="loading">
          <el-dropdown
            v-for="item in templateList"
            :key="item.id"
            trigger="contextmenu"
            placement="bottom-start"
            @command="(cmd: string) => onDropdownCommand(cmd, item)"
          >
            <div
              class="grid-item"
              :class="{ selected: isBatchMode && selectedIds.includes(item.id) }"
              @click="handleItemClick(item)"
            >
              <div class="item-checkbox" v-if="isBatchMode" @click.stop>
                <el-checkbox
                  :model-value="selectedIds.includes(item.id)"
                  @change="handleSelectChange(item.id, $event)"
                />
              </div>
              <div class="item-icon">
                <el-icon :size="48" color="#409EFF"><Document /></el-icon>
              </div>
              <div class="item-name" :title="item.name">{{ item.name }}</div>
              <div class="item-meta">
                <span>v{{ item.version || 1 }}</span>
                <span>{{ formatTime(item.createTime) }}</span>
              </div>
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="download">
                  <el-icon style="margin-right:6px;"><Download /></el-icon>下载
                </el-dropdown-item>
                <el-dropdown-item command="delete" divided>
                  <el-icon style="margin-right:6px;"><Delete /></el-icon>删除
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-empty v-if="!loading && templateList.length === 0" description="暂无模板数据" />
        </div>
  
        <!-- 列表视图 - 移除右键菜单 -->
        <div v-if="viewMode === 'list'" class="list-view">
          <el-table
            :data="templateList"
            v-loading="loading"
            stripe
            border
            style="width: 100%"
            @row-click="handleRowClick"
            :row-class-name="getRowClassName"
          >
            <el-table-column
              v-if="isBatchMode"
              type="selection"
              width="55"
              :selectable="() => true"
              :reserve-selection="true"
            />
            <el-table-column type="index" label="序号" width="60" align="center" />
            <el-table-column prop="name" label="模板名称" min-width="200" show-overflow-tooltip>
              <template #default="{ row }">
                <div style="display: flex; align-items: center;">
                  <el-icon style="margin-right: 8px; color: #409EFF"><Document /></el-icon>
                  <span>{{ row.name }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="version" label="版本" width="100" align="center">
              <template #default="{ row }">
                <el-tag type="info" size="small">v{{ row.version || 1 }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="remark" label="备注" min-width="200" show-overflow-tooltip>
              <template #default="{ row }">
                <span>{{ row.remark || '-' }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180" align="center">
              <template #default="{ row }">
                {{ formatTime(row.createTime) }}
              </template>
            </el-table-column>
          </el-table>
          <el-empty v-if="!loading && templateList.length === 0" description="暂无模板数据" />
        </div>
      </div>
  
      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.size"
          :total="pagination.total"
          :page-sizes="[10, 20, 30, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
  
      <!-- 占位符对话框 -->
      <el-dialog
        v-model="placeholderDialogVisible"
        title="模板占位符"
        width="520px"
        :close-on-click-modal="false"
      >
        <el-table
          :data="placeholderList"
          border
          height="360px"
          v-loading="placeholderLoading"
        >
          <el-table-column prop="key" label="占位符" min-width="200" />
          <el-table-column prop="value" label="说明" min-width="260" />
        </el-table>
        <template #footer>
          <el-button @click="placeholderDialogVisible = false">关闭</el-button>
          <el-button type="primary" :loading="placeholderExporting" @click="handleExportPlaceholders">
            导出 Excel
          </el-button>
        </template>
      </el-dialog>

      <!-- 上传对话框 -->
      <el-dialog
        v-model="uploadDialogVisible"
        title="上传测试模板"
        width="500px"
        :close-on-click-modal="false"
      >
        <el-form
          ref="uploadFormRef"
          :model="uploadForm"
          :rules="uploadRules"
          label-width="100px"
        >
          <el-form-item label="模板名称" prop="name">
            <el-input
              v-model="uploadForm.name"
              placeholder="请输入模板名称"
              clearable
            />
          </el-form-item>
          <el-form-item label="版本号" prop="version">
            <el-input-number
              v-model="uploadForm.version"
              :min="1"
              :precision="0"
              placeholder="请输入版本号"
              style="width: 100%"
            />
          </el-form-item>
          <el-form-item label="备注" prop="remark">
            <el-input
              v-model="uploadForm.remark"
              type="textarea"
              :rows="3"
              placeholder="请输入备注（可选）"
              maxlength="500"
              show-word-limit
              clearable
            />
          </el-form-item>
          <el-form-item label="模板文件">
            <el-upload
              ref="uploadRef"
              :auto-upload="false"
              :limit="1"
              :on-change="handleFileChange"
              :on-remove="handleFileRemove"
              :file-list="uploadForm.fileList"
              accept=".doc,.docx,.xls,.xlsx"
            >
              <el-button type="primary">选择文件</el-button>
              <template #tip>
                <div class="el-upload__tip">
                  仅支持Word(.doc/.docx)和Excel(.xls/.xlsx)文件
                </div>
              </template>
            </el-upload>
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="uploadDialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="uploading" @click="handleSubmitUpload">
            确定
          </el-button>
        </template>
      </el-dialog>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, reactive, onMounted, onUnmounted } from 'vue'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import type { FormInstance, UploadFile, UploadFiles } from 'element-plus'
import {
    Upload,
    Search,
    Delete,
    Download,
    Document,
    Grid,
    List,
    Select,
    Tickets
  } from '@element-plus/icons-vue'
import {
    pageTestTemplates,
    deleteTestTemplate,
    deleteTestTemplates,
    downloadTestTemplate,
    uploadTestTemplate,
    listTemplatePlaceholders,
    exportTemplatePlaceholders,
    type TestTemplate,
    type TestTemplateQuery,
    type TemplatePlaceholderKV
  } from '@/apis/template/testTemplate'
  import { useDownload } from '@/hooks'
  
const templateList = ref<TestTemplate[]>([])
const loading = ref(false)
const viewMode = ref<'grid' | 'list'>('grid')
const isBatchMode = ref(false)
const selectedIds = ref<number[]>([])
const selectedTemplate = ref<TestTemplate | null>(null)

// 占位符相关
const placeholderDialogVisible = ref(false)
const placeholderLoading = ref(false)
const placeholderExporting = ref(false)
const placeholderList = ref<TemplatePlaceholderKV[]>([])
  
  // 上传相关
  const uploadDialogVisible = ref(false)
  const uploading = ref(false)
  const uploadFormRef = ref<FormInstance>()
  const uploadRef = ref()
  const uploadForm = reactive({
    name: '',
    version: 1,
    remark: '',
    file: null as File | null,
    fileList: [] as UploadFiles
  })
  
  const uploadRules = {
    name: [
      { required: true, message: '请输入模板名称', trigger: 'blur' },
      { max: 100, message: '模板名称长度不能超过100个字符', trigger: 'blur' }
    ],
    version: [
      { required: true, message: '请输入版本号', trigger: 'blur' },
      { type: 'number' as const, min: 1, message: '版本号必须大于0', trigger: 'blur' }
    ]
  }
  
  const queryForm = reactive<Partial<TestTemplateQuery>>({
    name: undefined
  })
  
  const pagination = reactive({
    page: 1,
    size: 30,
    total: 0
  })
  
  // 格式化时间
  const formatTime = (time?: string) => {
    if (!time) return '-'
    return new Date(time).toLocaleString('zh-CN')
  }
  
  // 获取模板列表
  const fetchTemplateList = async () => {
    loading.value = true
    try {
      const query: TestTemplateQuery = {
        name: queryForm.name,
        version: queryForm.version,
        page: pagination.page,
        size: pagination.size
      }
      const res = await pageTestTemplates(query)
      if (res && res.data && res.data.data) {
        const pageData = res.data.data
        if (pageData.list && Array.isArray(pageData.list)) {
          templateList.value = pageData.list
          pagination.total = pageData.total || 0
        } else if (Array.isArray(pageData)) {
          templateList.value = pageData
          pagination.total = pageData.length
        } else {
          templateList.value = []
          pagination.total = 0
        }
      } else {
        templateList.value = []
        pagination.total = 0
      }
    } catch (error) {
      console.error('获取模板列表失败:', error)
      ElMessage.error('获取模板列表失败')
      templateList.value = []
      pagination.total = 0
    } finally {
      loading.value = false
    }
  }
  
  // 搜索
  const handleSearch = () => {
    pagination.page = 1
    fetchTemplateList()
  }
  
  // 分页大小改变
  const handleSizeChange = (size: number) => {
    pagination.size = size
    pagination.page = 1
    fetchTemplateList()
  }
  
  // 页码改变
  const handlePageChange = (page: number) => {
    pagination.page = page
    fetchTemplateList()
  }
  
  // 上传
  const handleUpload = () => {
    uploadForm.name = ''
    uploadForm.version = 1
    uploadForm.remark = ''
    uploadForm.file = null
    uploadForm.fileList = []
    uploadDialogVisible.value = true
  }
  
  // 文件选择变化
  const handleFileChange = (file: UploadFile) => {
    uploadForm.file = file.raw as File
  }
  
  // 文件移除
  const handleFileRemove = () => {
    uploadForm.file = null
  }

// 打开占位符对话框
const openPlaceholderDialog = async () => {
  placeholderDialogVisible.value = true
  placeholderLoading.value = true
  try {
    const res = await listTemplatePlaceholders()
    placeholderList.value = res.data?.data || []
  } catch (error) {
    console.error('获取占位符失败:', error)
    ElMessage.error('获取占位符失败')
  } finally {
    placeholderLoading.value = false
  }
}

const handleExportPlaceholders = async () => {
  try {
    placeholderExporting.value = true
    await useDownload(() => exportTemplatePlaceholders(), false, '模板占位符', '.xlsx')
    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出占位符失败:', error)
    ElMessage.error('导出占位符失败')
  } finally {
    placeholderExporting.value = false
  }
}
  
  // 提交上传
  const handleSubmitUpload = async () => {
    if (!uploadFormRef.value) return
    
    try {
      await uploadFormRef.value.validate()
      
      if (!uploadForm.file) {
        ElMessage.warning('请选择模板文件')
        return
      }
      
      // 验证文件类型
      const fileName = uploadForm.file.name
      const extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase()
      if (!['doc', 'docx', 'xls', 'xlsx'].includes(extension)) {
        ElMessage.error('仅支持Word(.doc/.docx)和Excel(.xls/.xlsx)文件')
        return
      }
      
      uploading.value = true
      try {
        await uploadTestTemplate(
          uploadForm.file,
          uploadForm.name,
          uploadForm.version,
          uploadForm.remark
        )
        ElMessage.success('上传成功')
        uploadDialogVisible.value = false
        await fetchTemplateList()
      } catch (error: any) {
        console.error('上传失败:', error)
        ElMessage.error(error?.message || '上传失败，请稍后重试')
      } finally {
        uploading.value = false
      }
    } catch (error) {
      console.error('表单验证失败:', error)
    }
  }
  
  // 网格项点击
  const handleItemClick = (item: TestTemplate) => {
    if (isBatchMode.value) {
      handleSelectChange(item.id, !selectedIds.value.includes(item.id))
    } else {
      selectedTemplate.value = item
    }
  }
  
  // 选择改变
  const handleSelectChange = (id: number, checked: boolean | string | number) => {
    const isChecked = Boolean(checked)
    if (isChecked) {
      if (!selectedIds.value.includes(id)) {
        selectedIds.value.push(id)
      }
    } else {
      const index = selectedIds.value.indexOf(id)
      if (index > -1) {
        selectedIds.value.splice(index, 1)
      }
    }
  }
  
  // 批量删除
  const handleBatchDelete = async () => {
    if (selectedIds.value.length === 0) {
      ElMessage.warning('请选择要删除的模板')
      return
    }
  
    try {
      await ElMessageBox.confirm(
        `确定要删除选中的 ${selectedIds.value.length} 个模板吗？`,
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
  
      await deleteTestTemplates(selectedIds.value)
      ElMessage.success('删除成功')
      selectedIds.value = []
      await fetchTemplateList()
    } catch (error) {
      if (error !== 'cancel') {
        console.error('批量删除失败:', error)
        ElMessage.error('批量删除失败')
      }
    }
  }
  
  // 行点击事件
  const handleRowClick = (row: TestTemplate) => {
    if (isBatchMode.value) {
      handleSelectChange(row.id, !selectedIds.value.includes(row.id))
    } else {
      selectedTemplate.value = row
    }
  }
  
  // 下拉菜单命令（网格项右键）
  const onDropdownCommand = async (cmd: string, item: TestTemplate) => {
    selectedTemplate.value = item
    if (cmd === 'download') {
      await handleDownload()
    } else if (cmd === 'delete') {
      await handleDelete()
    }
  }
  
  // 下载模板
  const handleDownload = async () => {
    if (!selectedTemplate.value) return
  
    try {
      await useDownload(
        () => downloadTestTemplate(selectedTemplate.value!.id),
        false,
        selectedTemplate.value.name || 'template',
        '.docx'
      )
      ElMessage.success('下载成功')
    } catch (error) {
      console.error('下载模板失败:', error)
      ElMessage.error('下载模板失败')
  } finally {
      // no-op
    }
  }
  
  // 删除模板
  const handleDelete = async () => {
    if (!selectedTemplate.value) return
  
    try {
      await ElMessageBox.confirm(
        `确定要删除模板「${selectedTemplate.value.name}」吗？`,
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
  
      await deleteTestTemplate(selectedTemplate.value.id)
      ElMessage.success('删除成功')
      await fetchTemplateList()
    } catch (error) {
      if (error !== 'cancel') {
        console.error('删除模板失败:', error)
        ElMessage.error('删除模板失败')
      }
    } finally {
      // no-op
    }
  }
  
  // 获取行类名
  const getRowClassName = ({ row }: { row: TestTemplate }) => {
    return isBatchMode.value && selectedIds.value.includes(row.id) ? 'selected-row' : ''
  }
  
  onMounted(() => {
    fetchTemplateList()
  })
  
  onUnmounted(() => {
  })
  </script>
  
  <style scoped lang="scss">
  .template-manager {
    padding: 20px;
    height: 100%;
    display: flex;
    flex-direction: column;
    background: #f5f7fa;
  
    .header-toolbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      padding: 16px 20px;
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
  
      .toolbar-left {
        display: flex;
        align-items: center;
      }
  
      .toolbar-right {
        display: flex;
        align-items: center;
      }
    }
  
    .content-area {
      flex: 1;
      overflow: auto;
      margin-bottom: 16px;
  
      .grid-view {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
        gap: 20px;
        padding: 20px;
        background: #fff;
        border-radius: 8px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
  
        .grid-item {
          position: relative;
          padding: 16px;
          border: 1px solid var(--el-border-color);
          border-radius: 8px;
          cursor: pointer;
          transition: all 0.3s;
          background: #fff;
  
          &:hover {
            border-color: var(--el-color-primary);
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
          }
  
          &.selected {
            border-color: var(--el-color-primary);
            background: var(--el-color-primary-light-9);
          }
  
          .item-checkbox {
            position: absolute;
            top: 8px;
            right: 8px;
            z-index: 1;
          }
  
          .item-icon {
            display: flex;
            justify-content: center;
            margin-bottom: 12px;
          }
  
          .item-name {
            text-align: center;
            font-size: 14px;
            color: var(--el-text-color-primary);
            margin-bottom: 8px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }
  
          .item-meta {
            display: flex;
            justify-content: space-between;
            font-size: 12px;
            color: var(--el-text-color-secondary);
          }
        }
      }
  
      .list-view {
        height: 100%;
        background: #fff;
        border-radius: 8px;
        padding: 16px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);

        :deep(.selected-row) {
          background-color: var(--el-color-primary-light-9);
        }

        :deep(.el-table) {
          .el-table__header {
            th {
              background-color: #f5f7fa;
              font-weight: 600;
              color: var(--el-text-color-primary);
            }
          }

          .el-table__body {
            tr {
              &:hover {
                background-color: #f5f7fa;
                cursor: pointer;
              }
            }
          }
        }
      }
    }
  
    .pagination-wrapper {
      display: flex;
      justify-content: flex-end;
      padding-top: 16px;
      border-top: 1px solid var(--el-border-color-lighter);
    }
  
    .context-menu {
      position: fixed;
      z-index: 99999;
      background: var(--el-bg-color);
      border: 1px solid var(--el-border-color);
      border-radius: 4px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      padding: 4px 0;
      min-width: 120px;
      pointer-events: auto;
  
      .menu-item {
        display: flex;
        align-items: center;
        padding: 8px 16px;
        cursor: pointer;
        font-size: 14px;
        color: var(--el-text-color-primary);
        transition: background-color 0.2s;
  
        &:hover {
          background-color: var(--el-fill-color-light);
        }
  
        &.danger {
          color: var(--el-color-danger);
  
          &:hover {
            background-color: var(--el-color-danger-light-9);
          }
        }
  
        .el-icon {
          margin-right: 8px;
          font-size: 16px;
        }
      }
    }
  
    /* 自定义右键菜单相关样式已移除，改用 el-dropdown */
  }
  </style>